package com.xxm.audio_view

import android.annotation.SuppressLint
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.AudioRecord.OnRecordPositionUpdateListener
import android.media.MediaRecorder
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

@SuppressLint("MissingPermission")
class AudioRecordView {
    private val TAG = "AudioRecordView"

    private var audioRecord: AudioRecord? = null

    private val BAD_VALUE = -2

    private var minBufferSize: Int = 0

    var callback: AudioRecordView.AudioCallback? = null

    private var job: Job? = null

    fun initAudioRecord() {
        val bufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)
        if (bufferSize == BAD_VALUE) {
            Log.d(TAG, "初始化AudioRecord最小值失败")
        }

        minBufferSize = minBufferSize * 2
    }

    @SuppressLint("MissingPermission")
    fun start() {
        if (minBufferSize == 0 || minBufferSize == BAD_VALUE) {
            Log.d(TAG, "初始化失败")
            return
        }

        audioRecord = AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT,minBufferSize)

        val byteBuffer = ByteArray(minBufferSize)

        job = GlobalScope.launch(Dispatchers.IO) {
            audioRecord?.setRecordPositionUpdateListener(object : OnRecordPositionUpdateListener {
                override fun onMarkerReached(recorder: AudioRecord?) {

                }

                override fun onPeriodicNotification(recorder: AudioRecord?) {
                    Log.d(TAG, "onPeriodicNotification")
                    val result = audioRecord?.read(byteBuffer, 0, byteBuffer.size)
                    if (audioRecord?.recordingState == AudioRecord.RECORDSTATE_RECORDING && result != -1) {
                        callback?.onAudioBuffer(byteBuffer)
                        Log.d(TAG, "read audio data success")
                    } else {
                        Log.d(TAG, "read audio data error:${result},state:${audioRecord?.recordingState}")
                    }
                }

            })
            audioRecord?.startRecording()
        }
    }

    fun stop() {
        audioRecord?.stop()
    }

    fun resume() {
        audioRecord?.startRecording()
    }

    fun release() {
        job?.cancel()
        audioRecord?.stop()
        audioRecord?.release()
        audioRecord = null
    }

    interface AudioCallback {
        fun onAudioBuffer(byteArray: ByteArray)
    }

}